<!--
 * @Author: Aaron
 * @Date: 2022-01-17 16:38:59
 * @LastEditors: Even Liu
 * @LastEditTime: 2022-11-09 14:46:06
 * @Description: file content
 * @FilePath: \ias_ui\src\views\coi\components\pictureUpload.vue
 * @Company: 沃尔玛
-->
<template>
  <div class="uploadPhoto">
    <draggable v-model="fileList[path]" animation="300" class="draggable" :disabled="isDisabled && isDraggable" :handle="'.elImg'" @end="transEnd">
      <transition-group class="transition-group">
        <div v-for="img in fileList[path]" :key="JSON.stringify(img)" class="elImg">
          <el-image :src="img[urlName] | transImgUrl" :preview-src-list="transUrlName(fileList[path], urlName)" />
          <div v-if="!isDisabled" class="del" @click="del(img)">
            <i class="el-icon-delete" />
          </div>
        </div>
      </transition-group>
    </draggable>
    <el-upload
      v-if="fileList[path] && fileList[path].length < picNumber && !isDisabled"
      :auto-upload="false"
      :on-change="handleOnChange"
      :before-upload="onProgress"
      class="avatar-uploader"
      action="#"
      :accept="type | transType"
      :show-file-list="false"
      :multiple="multiple"
    >
      <i class="el-icon-plus avatar-uploader-icon" />
    </el-upload>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import eventBus from '@/utils/eventBus'
import { authentication } from '@/utils/processingData.js'

export default {
  name: 'PictureUpload',
  components: {
    draggable
  },
  filters: {
    transImgUrl(url) {
      return authentication(url)
    },
    transType(v) {
      return v.map((_) => `.${_}`).join(',')
    }
  },
  props: {
    fileList: {
      type: Object,
      default() {
        return {
          mainGraph: []
        }
      }
    },
    path: {
      type: String,
      default: ''
    },
    queryData: {
      type: Object,
      default() {
        return {}
      }
    },
    picNumber: {
      type: Number,
      default: 1
    },
    picSize: {
      type: Number,
      default: 3
    },
    multiple: {
      type: Boolean,
      default: false
    },
    isDisabled: {
      type: Boolean,
      default: false
    },
    isDraggable: {
      type: Boolean,
      default: true
    },
    urlName: {
      type: String,
      default: 'resourceUrl'
    },
    uploadDataKey: {
      type: Array,
      default() {
        return []
      }
    },
    delDataKey: {
      type: Array,
      default() {
        return []
      }
    },
    uploadFun: {
      type: Function,
      required: true
    },
    delFun: {
      type: Function,
      required: true
    },
    type: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      num: 0
    }
  },
  methods: {
    transEnd() {
      eventBus.$emit('operationCodeChange', this.path)
    },
    transUrlName(imgArr, urlName) {
      return imgArr.map((e) => authentication(e[urlName]))
    },
    del(img) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.delRequest(img)
        })
        .catch(() => {})
    },
    async delRequest(img) {
      try {
        eventBus.$emit('loadingChange', true)
        const queryData = {}
        this.delDataKey.forEach((_) => {
          queryData[_.key] = this.queryData[_.value] || img[_.value]
        })
        const { code } = await this.delFun(queryData)
        if (code === '0') {
          const index = this.fileList[this.path].findIndex((_) => _[this.urlName] === img[this.urlName])
          this.fileList[this.path].splice(index, 1)
          this.$message({
            type: 'success',
            message: '删除成功'
          })
        }
        eventBus.$emit('operationCodeChange', this.path)
      } finally {
        eventBus.$emit('loadingChange', false)
      }
    },
    onProgress() {
      console.log('onProgress')
    },
    handleOnChange(file, fileList) {
      console.log(file, fileList, 'change')
      const flag_Num = this.fileList[this.path].length + fileList.length > this.picNumber
      setTimeout(() => {
        fileList.length = 0
      }, 200)
      if (flag_Num) return this.$message.error(`图片的数量不能超过${this.picNumber}张`)

      if (Array.isArray(this.type) && this.type.length) {
        const flag_type = this.type.some((_) => {
          return file.raw.type.includes(_)
        })
        if (!flag_type) return this.$message.error(`仅支持上传${this.type.join('、')}格式的图片！`)
      }
      var size = file.size / 1024 / 1024
      if (size > this.picSize) return this.$message.error(`图片大小大于${this.picSize}M`)
      this.uploadRequest(file)
    },
    async uploadRequest(file) {
      try {
        this.num++
        eventBus.$emit('loadingChange', true)
        const formData = new FormData()
        // formData.append('file', file.raw)
        // this.uploadDataKey记得传递一个{key:'file',value:'raw'}
        this.uploadDataKey.forEach((_) => {
          formData.append(_.key, this.queryData[_.value] || file[_.value])
        })
        const { code, result } = await this.uploadFun(formData)
        if (code !== '0' && !result) return
        this.fileList[this.path].push(result)
        this.$message({
          type: 'success',
          message: '图片上传成功'
        })
        eventBus.$emit('operationCodeChange', this.path)
      } finally {
        this.num--
        if (this.num === 0) eventBus.$emit('loadingChange', false)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
$size: 100px;
.uploadPhoto {
  min-height: 110px;
  padding: 5px 0;
  display: flex;
  flex-wrap: wrap;
  .elImg {
    height: $size;
    width: $size;
    display: inline-block;
    margin-right: 10px !important;
    margin-bottom: 10px !important;
    position: relative;
    &:hover .del {
      display: block;
      height: 18px;
    }
    .del {
      line-height: 15px;
      border-radius: 1px;
      text-align: center;
      width: 100%;
      height: 0;
      overflow: hidden;
      position: absolute;
      left: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.3);
      cursor: pointer;
      color: #fff;
      font-size: 14px;
      transition: linear all 0.3s;
      .el-icon-delete {
        margin: 2px 0;
      }
    }
    /deep/ .el-image {
      border-radius: 5px;
      height: 100%;
      width: 100%;
    }
  }
}
.tip {
  padding: 0 10px;
  font-size: 14px;
  color: rgb(176, 176, 176);
}
.avatar-uploader /deep/ .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader /deep/ .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: $size;
  height: $size;
  line-height: $size;
  text-align: center;
}
.avatar {
  width: $size;
  height: $size;
  display: block;
}
.transition-group {
  display: inline-block;
  height: 100%;
}
</style>
